package com.talent.utils;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.talent.pojo.dto.OperationLogDetailDTO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import jakarta.servlet.http.HttpServletRequest;

/**
 * 操作日志工具类
 */
@Slf4j
public class OperationLogUtils {

    private static final ObjectMapper objectMapper;
    
    static {
        objectMapper = new ObjectMapper();
        // 注册Java 8时间模块
        objectMapper.registerModule(new JavaTimeModule());
        // 禁用将日期写为时间戳的功能
        objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
    }

    /**
     * 构建创建操作日志
     */
    public static OperationLogDetailDTO buildCreateLog(String resourceType, Long resourceId, String resourceName, Object newData) {
        return OperationLogDetailDTO.builder()
                .action("CREATE")
                .actionDetail("新增" + getResourceTypeName(resourceType) + "：" + resourceName)
                .resourceType(resourceType)
                .resourceId(resourceId)
                .resourceName(resourceName)
                .newData(newData)
                .ipAddress(getClientIpAddress())
                .userAgent(getUserAgent())
                .build();
    }

    /**
     * 构建更新操作日志
     */
    public static OperationLogDetailDTO buildUpdateLog(String resourceType, Long resourceId, String resourceName, Object oldData, Object newData) {
        return OperationLogDetailDTO.builder()
                .action("UPDATE")
                .actionDetail("修改" + getResourceTypeName(resourceType) + "：" + resourceName)
                .resourceType(resourceType)
                .resourceId(resourceId)
                .resourceName(resourceName)
                .oldData(oldData)
                .newData(newData)
                .ipAddress(getClientIpAddress())
                .userAgent(getUserAgent())
                .build();
    }

    /**
     * 构建删除操作日志
     */
    public static OperationLogDetailDTO buildDeleteLog(String resourceType, Long resourceId, String resourceName, Object oldData) {
        return OperationLogDetailDTO.builder()
                .action("DELETE")
                .actionDetail("删除" + getResourceTypeName(resourceType) + "：" + resourceName)
                .resourceType(resourceType)
                .resourceId(resourceId)
                .resourceName(resourceName)
                .oldData(oldData)
                .ipAddress(getClientIpAddress())
                .userAgent(getUserAgent())
                .build();
    }

    /**
     * 构建自定义操作日志
     */
    public static OperationLogDetailDTO buildCustomLog(String action, String actionDetail, String resourceType, Long resourceId, String resourceName) {
        return OperationLogDetailDTO.builder()
                .action(action)
                .actionDetail(actionDetail)
                .resourceType(resourceType)
                .resourceId(resourceId)
                .resourceName(resourceName)
                .ipAddress(getClientIpAddress())
                .userAgent(getUserAgent())
                .build();
    }

    /**
     * 将对象转换为JSON字符串
     */
    public static String toJsonString(Object obj) {
        if (obj == null) {
            return null;
        }
        try {
            return objectMapper.writeValueAsString(obj);
        } catch (JsonProcessingException e) {
            log.error("对象转JSON失败", e);
            return obj.toString();
        }
    }

    /**
     * 获取资源类型中文名称
     */
    private static String getResourceTypeName(String resourceType) {
        switch (resourceType) {
            case "spot":
                return "点位";
            case "category":
                return "分类";
            case "user":
                return "用户";
            case "menu":
                return "菜单";
            default:
                return resourceType;
        }
    }

    /**
     * 获取客户端IP地址
     */
    private static String getClientIpAddress() {
        try {
            ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
            if (attributes != null) {
                HttpServletRequest request = attributes.getRequest();
                String ip = request.getHeader("X-Forwarded-For");
                if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
                    ip = request.getHeader("Proxy-Client-IP");
                }
                if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
                    ip = request.getHeader("WL-Proxy-Client-IP");
                }
                if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
                    ip = request.getRemoteAddr();
                }
                // 多个IP时取第一个
                if (ip != null && ip.contains(",")) {
                    ip = ip.split(",")[0].trim();
                }
                return ip;
            }
        } catch (Exception e) {
            log.error("获取客户端IP地址失败", e);
        }
        return "unknown";
    }

    /**
     * 获取用户代理
     */
    private static String getUserAgent() {
        try {
            ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
            if (attributes != null) {
                HttpServletRequest request = attributes.getRequest();
                return request.getHeader("User-Agent");
            }
        } catch (Exception e) {
            log.error("获取用户代理失败", e);
        }
        return "unknown";
    }
}
